package com.tangruojie.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;

import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Date;

/**
 * JWT 工具类
 */
public class JwtUtils {

    /**
     * 密钥
     */
    private final SecretKey secretKey;
    /**
     * 签发者
     */
    private final String issuer;
    /**
     * 过期时间（毫秒）
     */
    private final long expireMillis;

    public JwtUtils(String secret, String issuer, long expireMinutes) {
        this.secretKey = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
        this.issuer = issuer;
        this.expireMillis = expireMinutes * 60_000L;
    }

    /**
     * 创建令牌
     *
     * @param subject
     * @return
     */
    public String generateToken(String subject) {
        Instant now = Instant.now(); // 当前时间
        return Jwts.builder() // 创建 JWT 构建器
                .subject(subject) // 令牌主题
                .issuer(issuer) // 令牌签发者
                .issuedAt(Date.from(now)) // 令牌签发时间
                .expiration(Date.from(now.plusMillis(expireMillis))) // 令牌过期时间
                .signWith(secretKey) // 签名
                .compact(); // 创建令牌
    }

    /**
     * 解析令牌并验证
     *
     * @param token
     * @return
     */
    public Claims parseAndValidate(String token) {
        try {
            return Jwts.parser() // 创建 JWT 解析器
                    .verifyWith(secretKey) // 验证签名
                    .requireIssuer(issuer) // 验证签发者
                    .build() // 创建解析器
                    .parseSignedClaims(token) // 解析令牌
                    .getPayload(); // 获取令牌内容
        } catch (Exception e) {
            throw new RuntimeException("令牌无效");
        }
    }

    /**
     * 获取用户Id
     *
     * @param token
     * @return
     */
    public String getId(String token) {
        return parseAndValidate(token).getSubject(); // 获取用户Id
    }

}
